package cn.hinglo.permission.service;

import cn.hinglo.common.cache.SelfCacheKit;
import cn.hinglo.common.constant.SystemConstant;
import cn.hinglo.common.entity.Result;
import cn.hinglo.common.exception.ResultException;
import cn.hinglo.common.util.ResultKit;
import cn.hinglo.common.util.SysCommonKit;
import cn.hinglo.permission.model.Permission;
import cn.hinglo.permission.model.Services;
import cn.hinglo.permission.model.User;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author HingLo
 * @createTime: 2018/11/15 15:12
 * @description: 登录先关的服务层
 */
public class LoginService {
    /***
     * 错误次数超过多少就不能登录了
     */
    private static final int errorMax = 3;

    /**
     * 登录账号
     *
     * @param username 用户名，即唯一的员工编号
     * @param password 员工的唯一密码
     * @return 是否登录成功
     */
    public User loginMethodService(String username, String password) {
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return null;
        }
        // 登录错误次数校验
        Integer errorCount = SelfCacheKit.get(SystemConstant.LOGIN_ERROR, username);
        if (errorCount != null && errorCount >= errorMax) {
            throw new ResultException(-1, "登录过于频繁,请稍后再试");
        }
        if (StrKit.notBlank(username, password)) {
            String sql = Db.getSql("user.Login-login");
            User user = User.dao.findFirst(sql, username, md5UserPassword(username, password));
            if (user != null) {
                return user;
            }
        }
        // 错误次数+1
        if (errorCount == null) {
            errorCount = 1;
        } else {
            errorCount++;
        }
        // 登录次数错误记录
        SelfCacheKit.put(SystemConstant.LOGIN_ERROR, username, errorCount);
        return null;
    }

    /**
     * 通过指定的用户名来查询全部的权限
     *
     * @param id 员工唯一id
     * @return 权限的集合
     */
    public Record findPermissionService(Integer id) {
        // 获取系统中用的服务
        List<Services> servicesList = this.listService();
        Record record = new Record();
        if (servicesList.isEmpty()) {
            return record;
        }
        Map<Integer, String> serviceMap = new HashMap<>(servicesList.size());
        servicesList.forEach(action -> serviceMap.put(action.getId(), action.getUrl()));
        // 获取用用户的权限
        String sql = Db.getSql("user.Login-permission");
        List<Permission> permissionList = Permission.dao.find(sql, id);
        // 1：移除服务异常的接口权限，2：讲权限地址组成一个完整的地址
        permissionList.forEach(action -> {
            Integer serverId = action.getServerId();
            String serviceUrl = serviceMap.get(serverId);
            if (serviceMap.containsKey(serverId)) {
                if (!"/".equals(serviceUrl)) {
                    action.setUrl(serviceUrl + action.getUrl());
                }
                record.set(action.getId().toString(), action.getUrl());
            }
        });
        return record;

    }

    /***
     * 查询系统中可以的服务信息
     *
     * @return 返回结果
     */
    public List<Services> listService() {
        String sql = Db.getSql("user.List-service");
        return Services.dao.find(sql);
    }

    /**
     * @param id 用户的唯一Id
     * @return 返回该用户递归好的全部菜单权限
     */
    public List<Record> findMenuService(Integer id) {
        String sql = Db.getSql("user.Login-menu");
        List<Record> list = Db.find(sql, id);
        return SysCommonKit.createTreeMenuKit(list);
    }


    /***
     * 修改密码
     *
     * @param userId 用户ID
     * @param newPassword 新密码
     * @return 返回修改结果
     */
    public Result updatePassword(String userId, String password, String newPassword) {

        if (!StrKit.notBlank(userId, password, newPassword)) {
            return ResultKit.error("信息校未通过,请稍后重试");
        }

        User user = User.dao.findById(userId);
        if (user == null) {
            return ResultKit.error("用户不存在");
        }
        if (StrUtil.equals(user.getPassword(), md5UserPassword(user.getUsername(), password))) {
            user.setPassword(md5UserPassword(user.getUsername(), newPassword));
            return user.update() ? ResultKit.success() : ResultKit.error("密码修改失败");
        }
        return ResultKit.error("旧密码不正确,请稍后重试");
    }

    /***
     * 用户密码加密规则
     * @param username 用户名
     * @param password 密码
     * @return 返回加密后的密文
     */
    private String md5UserPassword(String username, String password) {
        return SecureUtil.md5(username + password);
    }

    /***
     * 重置密码
     * @param userId 用户名
     * @param password 新密码
     * @return 返回重置结果
     */
    public Result restPassword(String userId, String password) {
        User user = User.dao.findById(userId);
        if (user == null) {
            return ResultKit.error("用户不存在");
        }
        user.setPassword(md5UserPassword(user.getUsername(), password));
        return user.update() ? ResultKit.success() : ResultKit.error("密码重置失败");
    }
}
